<template>
  <!-- 导航栏 -->
  <scroll-view
    :scrollX="scroll"
    class="mxp-tabs"
    :showScrollbar="false"
    :scrollWithAnimation="true"
    :scrollIntoView="data.scrollInto"
    :style="[{ background, minHeight: height || '36px', width, borderRadius }, tabsStyle, cusStyle]"
  >
    <view
      v-for="(item, index) in newList"
      :id="`${baseId}-${index}`"
      :key="index"
      class="tab-item"
      :style="[
        {
          minHeight: height || '36px',
          width: item.itemWidth,
          minWidth: item.itemWidth,
          transitionDuration: showAnimation ? '0.3s' : '0s',
          opacity: !item.activIcon && index !== data.tabIndex ? 0.7 : 1,
          transform: `scale(${index === data.tabIndex ? item.activeScale || activeScale : 1})`,
        },
        item.itemStyle || {},
        itemStyle,
        { flexDirection: direction === 'column' ? 'column' : 'row' },
      ]"
      @click="setCurrentIndex(index)"
    >
      <mxp-icon-image
        v-if="item.icon"
        :icon="index === data.tabIndex ? item.activIcon || item.icon : item.icon"
        :size="item.iconSize || iconSize"
        :style="item.iconStyle"
        :cusStyle="imageStyle"
      ></mxp-icon-image>
      <view style="display: flex; align-items: center; justify-content: center">
        <text
          class="title vue"
          :style="{
            color: index === data.tabIndex ? item.activeColor || activeColor : item.color || color,
            fontWeight: bold && index === data.tabIndex ? 'bold' : 'normal',
            fontSize: item.fontSize || fontSize,
          }"
        >
          {{ item.label }}
        </text>
        <mxp-badge v-if="item.badge" :badge="item.badge" v-bind="{ ...badgeOption, ...item.badgeOption }"></mxp-badge>
      </view>
    </view>
    <!-- 下划线 -->
    <view
      v-if="showLine"
      class="under-line-box"
      :style="{ bottom: lineBottom, transform: `translateX(${data.lineTranslateX})`, height: lineHeight, width: newList[data.tabIndex]!.itemWidth }"
    >
      <view
        class="under-line"
        :style="[{ width: lineWidth || `calc(${newList[data.tabIndex]!.itemWidth} * 0.8)`, height: lineHeight, background: activeColor }, lineStyle]"
      ></view>
    </view>
  </scroll-view>
</template>

<script lang="ts" setup>
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import { type CSSProperties, type PropType, computed, onMounted, shallowReactive, watch } from 'vue';
  import type { $AllColorStr, $AllSizeUnitStr, $SizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import MxpBadge, { type $BadgeProps } from '../mxp-badge/mxp-badge.vue';
  import mxpIconImage from '../mxp-icon-image/mxp-icon-image.vue';
  import { getOnlyID } from '../mxp-tool/utils/common';

  export type $TabsItem = {
    [x: string]: unknown;
    /** 标题名称 */
    label: string;
    /** 图标 */
    icon?: string;
    /** 选中时图标 不传就显示未选中时的图标 */
    activIcon?: string;
    /** 图标大小 优先级高于在popup中设置的大小 */
    iconSize?: $SizeUnitStr;
    /** 角标 */
    badge?: number | string;
    /** 角标配置 */
    badgeOption?: $BadgeProps;
    /** 选中时的颜色 */
    activeColor?: $AllColorStr;
    /** 未选中时的颜色 */
    color?: $AllColorStr;
    /** 未选中时的颜色 */
    fontSize?: $SizeUnitStr;
    /** 选中时文字缩放比例.默认 1.1 */
    activeScale?: $SizeUnitStr;
    /** 每一个 tab 的宽度 单位为 px  */
    itemWidth?: $AllSizeUnitStr;
    /** 每个 tab 的样式 */
    itemStyle?: CSSProperties;
    /** 线条的样式 */
    lineStyle?: CSSProperties;
  };

  defineOptions({
    name: 'mxp-tabs',
  });

  const props = defineProps({
    /** 这个组件的宽度 [必传] */
    width: { type: String as PropType<$SizeUnitStr | `${number}%` | `calc(${string})`>, required: true },
    /** 整个组件的高度 */
    height: { type: String as PropType<$SizeUnitStr>, default: undefined },
    /** 当前的 index */
    current: { type: Number, default: 0 },
    /** 未选中时的颜色 */
    color: { type: String as PropType<$AllColorStr>, default: '#666666' },
    /** 选中时的颜色 */
    activeColor: { type: String as PropType<$AllColorStr>, default: '#223aec' },
    /** 未选中时的字体大小 */
    fontSize: { type: String as PropType<$SizeUnitStr>, default: '14px' },
    /** 超过一屏后是否可以滚动 */
    scroll: { type: Boolean, default: undefined },
    /** 未选中时的字体是否加粗 */
    bold: { type: Boolean, default: false },
    /** 选中时文字缩放比例.默认 1.1 */
    activeScale: { type: Number, default: 1.1 },
    /** 整个组件的背景 */
    background: { type: String as PropType<$AllColorStr>, default: 'rgba(0,0,0,0)' },
    /** 圆角 */
    borderRadius: { type: String as PropType<$SizeUnitStr>, default: '0px' },
    /** tab数组 [{  label: '全部', badge: 99 }] */
    list: { type: Array as PropType<($TabsItem | number | string)[]>, default: () => [] },
    /** 图标大小 优先级低于在list中设置的大小 */
    iconSize: { type: String as PropType<$SizeUnitStr>, default: '24px' },
    /** 图标和文字的排版方向 */
    direction: { type: String as PropType<'column' | 'row'>, default: 'row' },
    /** 是否显示动画 */
    showAnimation: { type: Boolean, default: true },
    /** 当 animationModel 为 line 时，文字是否显示缩放动画 */
    showLine: { type: Boolean, default: true },
    /** 线条宽度 */
    lineWidth: { type: String as PropType<$SizeUnitStr>, default: undefined },
    /** 线条的高度 */
    lineHeight: { type: String as PropType<$SizeUnitStr>, default: '2px' },
    /** 线条距离底部的距离 */
    lineBottom: { type: String as PropType<$SizeUnitStr>, default: '2px' },
    /** badge 的配置项目 */
    badgeOption: { type: Object as PropType<$BadgeProps>, default: () => ({}) },
    /** 整个 tabs 的样式 */
    tabsStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 每个 tab 的样式 */
    itemStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    /** 线条的样式 */
    lineStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
    ...publicStyeProps,
  });
  const emits = defineEmits<{
    (e: 'update:current', vul: number): void;
    (e: 'change', vul: number): void;
  }>();

  const baseId = getOnlyID('tabs');
  const data = shallowReactive({
    tabIndex: 0, // 导航栏被点击
    lineTranslateX: '0px', // 导航栏下划线位置偏移
    scrollInto: '',
  });

  const imageStyle = computed<CSSProperties>(() => {
    return props.direction === 'row' ? { marginRight: '4px' } : { marginBottom: '4px' };
  });

  watch(
    () => props.list,
    () => {
      init();
    }
  );

  watch(
    () => props.current,
    (vul, old) => {
      if (vul !== old) {
        setCurrentIndex(vul);
      }
    }
  );
  watch(
    () => data.tabIndex,
    (vul, old) => {
      if (vul !== old) {
        emits('change', vul); // 设置swiper的第几页
        emits('update:current', vul);
      }
    }
  );

  const newList = computed<$TabsItem[]>(() => {
    return props.list.map((item) => {
      if (typeof item === 'number' || typeof item === 'string') {
        return { label: item, badge: '', itemWidth: `calc(${props.width} / ${props.list.length})` } as $TabsItem;
      } else {
        item.itemWidth = item.itemWidth || `calc(${props.width} / ${props.list.length})`;
        return item;
      }
    });
  });

  onMounted(() => {
    setTimeout(() => {
      init();
    }, 10);
  });

  /** 初始化 */
  function init() {
    data.tabIndex = props.current; // 设置导航点击了哪一个
    data.lineTranslateX = `calc(100% * ${props.current})`; // 设置下划线位置偏移
    data.scrollInto = `${baseId}-${data.tabIndex}`;
  }

  /** 设置导航点击了哪一个 */
  function setCurrentIndex(index: number) {
    data.tabIndex = index; // 设置导航点击了哪一个
    data.lineTranslateX = `calc(100% * ${index})`; // 设置下划线位置偏移
    data.scrollInto = `${baseId}-${data.tabIndex}`;
  }

  defineExpose({
    /** 设置导航点击了哪一个 */
    setCurrentIndex,
  });
</script>

<style lang="scss" scoped>
  .mxp-tabs {
    position: relative;
    display: flex;
    flex-flow: row nowrap;
    align-items: flex-start;
    justify-content: center;
    white-space: nowrap;

    .tab-item {
      display: inline-flex;
      flex: 1;
      flex-flow: row nowrap;
      align-items: center;
      justify-content: center;
      color: #666666;
      text-align: center;
      transition-duration: 0.3s;
      transition-property: transform;

      .title {
        font-size: 14px;

        .vue {
          // #ifndef APP-NVUE
          transition-duration: 0.3s;
          transition-property: color;
          // #endif
        }
      }
    }

    .under-line-box {
      position: absolute;
      bottom: 4px;
      left: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 2px;
      transition-duration: 0.3s;
      transition-property: transform;

      .under-line {
        height: 2px;
        background-color: #223aec;
        border-radius: 99px;
      }
    }
  }
</style>
